#ifndef TRANSACTIONLOG_H_
#define TRANSACTIONLOG_H_

#include "BPlusPlus.h"
#include "Log.h"
#include <stdio.h>
#include <string>
#include <sstream>



class TransactionLog
{
public:
	static void Create(std::string filename)
	{
		char linea[80];		
		std::string logname("LOG");
		std::string toWrite("");
				
		logname += filename;
		
		unsigned int sizeFilename  = logname.size();
		logname.replace(sizeFilename -4, 1,".",1);
		logname.replace(sizeFilename -3, 1,"t",1);
		logname.replace(sizeFilename -2, 1,"x",1);
		logname.replace(sizeFilename -1, 1,"t",1);		

		memset(linea, '-', 79);
		linea[79]='\n';

		FILE * fd = fopen(logname.c_str(), "a");
		
		if(fd != NULL)
		{
			fputs(linea, fd);
			
			toWrite += "OPERATION: CREATE";
			toWrite += "\n";
			
			fputs(toWrite.c_str(), fd);
			
			toWrite = "";
			toWrite += "FILENAME: ";
			toWrite += filename;
			toWrite += "\n";
			
			fputs(toWrite.c_str(), fd);
						
			fclose(fd);
		}
	}
	static void Write(std::string filename, char* ptr, unsigned int size, int nrr)
	{
		char linea[80];		
		char ptrKey[4096];
		std::string logname("LOG");
		std::string toWrite("");
		std::stringstream ss;
		
		logname += filename;
		
		unsigned int sizeFilename  = logname.size();
		logname.replace(sizeFilename -4, 1,".",1);
		logname.replace(sizeFilename -3, 1,"t",1);
		logname.replace(sizeFilename -2, 1,"x",1);
		logname.replace(sizeFilename -1, 1,"t",1);		

		memset(linea, '-', 79);
		linea[79]='\n';
		
		memset(ptrKey, 0, 4096);
		memcpy(ptrKey, ptr, size);
		ptrKey[size] = '\0';

		FILE * fd = fopen(logname.c_str(), "a");
		
		if(fd != NULL)
		{
			fputs(linea, fd);
			
			toWrite += "OPERATION: ADD";
			toWrite += "\n";
			fputs(toWrite.c_str(), fd);
			
			toWrite = "";
			toWrite += "FILENAME: ";
			toWrite += filename;
			toWrite += "\n";
			fputs(toWrite.c_str(), fd);
			
			
			toWrite = "";
			toWrite += "KEY: ";
			toWrite += ptrKey;
			toWrite += "\n";
			fputs(toWrite.c_str(), fd);
			
			ss.str("");
			ss << size;
			
			toWrite = "";
			toWrite += "SIZE: ";
			toWrite += ss.str();
			toWrite += "\n";
			fputs(toWrite.c_str(), fd);
			
			ss.str("");
			ss << nrr;
			
			toWrite = "";
			toWrite += "VALUE: ";
			toWrite += ss.str();
			toWrite += "\n";
			fputs(toWrite.c_str(), fd);
						
			fclose(fd);
		}
	}
	
	static void CreateTree(char *nombre)
	{
		BPlusPlus * tree = new BPlusPlus();
		std::string filename(nombre);
		
		tree->create(filename);
		tree->close();
			
		delete tree;
	}
	
	static void AddInTree(int &contador, char *name, char *key, unsigned int size, int value)
	{
		std::string filename(name);
		BPlusPlus * tree = new BPlusPlus();
		std::stringstream ss;
				
		tree->open(filename);
		
		ss << contador;
		
		//Log::Write(ss.str());
		
		contador++;
		
		tree->add(key, size, value);
		
		tree->close();
		
		delete tree;
	}
	
	static void Reload(std::string filename)
	{
		char *ptr = NULL;
		char linea[200]={0};
		char ptrKey[4096]={0};
		char ptrValue[4096]={0};
		char ptrSize[100]={0};
		unsigned int size = 0;
		char nombre[200] = {0};
		unsigned int sizeName = 0;
		int value = 0;		
		int contador = 0;
		
		FILE * fd = fopen(filename.c_str(), "r");
		
		if(fd != NULL)
		{
			do
			{
				// Empiezo a tomar las lineas
				ptr = fgets(linea, 200, fd);
				
				if(ptr != 0)
				{
					switch(linea[0])
					{
						case '-' : break; // No me interesa esta linea
						case 'O' : { // Estoy en el caso de una operacion, determino cual es
							if(strncmp(linea + 11, "CREATE", 6) == 0)
							{
								// Estoy en el caso de la creacion
								// Tomo la siguiente linea para obtener el filename
								memset(linea, 0, 200);
								ptr = fgets(linea, 200, fd);
								if(ptr != 0)
								{								
									memset(nombre, 0, 200);
									memcpy(nombre, linea + 10, 100); // Se supone que mas de 100 no tiene
									sizeName = strlen(nombre);
									nombre[sizeName - 1] ='\0';
									TransactionLog::CreateTree(nombre);
								}
								else
								{
									std::cout << "ERROR DE LECTURA" << std::endl;
								}
							}
							else
							{
								// Estoy en el caso del alta, tengo que tomar el filename, key, size, value
								// Tomo la siguiente linea para obtener el filename
								memset(linea, 0, 200);
								ptr = fgets(linea, 200, fd);
								if(ptr != 0)
								{
									memset(nombre, 0, 200);
									memcpy(nombre, linea + 10, 100); // Se supone que mas de 100 no tiene
									sizeName = strlen(nombre);
									nombre[sizeName - 1] ='\0';
								}
								
								// Tomo la siguiente linea para obtener el value
								memset(linea, 0, 200);
								ptr = fgets(linea, 200, fd);
								if(ptr != 0)
								{
									memset(ptrKey, 0, 4096);
									memcpy(ptrKey, linea + 5, 100); // Se supone que mas de 100 no tiene
									ptrKey[strlen(ptrKey) - 1] = '\0';
								}
								
								// Tomo la siguiente linea para obtener el value
								memset(linea, 0, 200);
								ptr = fgets(linea, 200, fd);
								if(ptr != 0)
								{
									memset(ptrSize, 0, 100);
									memcpy(ptrSize, linea + 6, 94); // Se supone que mas de 100 no tiene
									ptrSize[strlen(ptrSize) - 1] = '\0';
									size = atoi(ptrSize);
								}
								
								// Tomo la siguiente linea para obtener el value
								memset(linea, 0, 200);
								ptr = fgets(linea, 200, fd);
								if(ptr != 0)
								{
									memset(ptrValue, 0, 100);
									memcpy(ptrValue, linea + 7, 94); // Se supone que mas de 100 no tiene
									ptrValue[strlen(ptrValue) - 1] = '\0';
									value = atoi(ptrValue);
								}
								
								TransactionLog::AddInTree(contador, nombre, ptrKey, size, value);
															
							}
							} break;
					};
				}
				else
				{
					std::cout << "ERROR DE LECTURA" << std::endl;
				}
				
				
			}while(!feof(fd));
		fclose(fd);
		}		
	}
};

#endif /*TRANSACTIONLOG_H_*/
